﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace colas
{
    class gridline
    {
        public double Reloj { get; set; }
        public int evento { get; set; }
        public double rnd_llegada { get; set; }
        public double rndn_llegada { get; set; }
        public double proxima_llegada_cliente { get; set; }
        public double rnd_eleccion { get; set; }
        public int eleccion { get; set; }
        public double fin_ticket { get; set; }
        public int estado_cajero { get; set; }
        public double cola_cajero { get; set; }
        public double cola_entrega { get; set; }
        public double rnd_entrega1 { get; set; }
        public double rnde_entrega1 { get; set; }
        public double fin_entrega1 { get; set; }
        public int estado_empleado1 { get; set; }
        public double rnd_entrega2 { get; set; }
        public double rnde_entrega2 { get; set; }
        public double fin_entrega2 { get; set; }
        public int estado_empleado2 { get; set; }
        public double rnd_eleccion_consumir { get; set; }
        public int eleccion_consumir { get; set; }
        public double rnd_consumicion { get; set; }
        public double rndu_consumicion { get; set; }
        public Cliente prox_cli_fin_comsumicion { get; set; }    //este atributo se usa cuando el próximo evento es fin_consumicion. El nuevo gridline va a calcular el clock con esto.
        public Cliente prox_cli_fin_utilizacion { get; set; }    //este atributo se usa cuando el próximo evento es fin_utilizacion. El nuevo gridline va a calcular el clock con esto.        
        public Cliente prox_cli_fin_paso { get; set; }           //este atributo se usa cuando el próximo evento es fin_paso. El nuevo gridline va a calcular el clock con esto.
        public double contador_personas { get; set; }
        public double acumulador_permanencia { get; set; }
        public static List<Cliente> clientes = new List<Cliente>();        
        private int tipoEvento;
        public Cliente cliente_actual { get; set; }
        
        

        //Constructor por defecto
        public gridline()            
        {
            inicializar();            
        }
        public gridline(gridline anterior)
        {
            this.acumulador_permanencia = anterior.acumulador_permanencia;
            this.cola_cajero = anterior.cola_cajero;
            this.cola_entrega = anterior.cola_entrega;
            this.contador_personas = anterior.contador_personas;
            this.estado_cajero = anterior.estado_cajero;
            this.estado_empleado1 = anterior.estado_empleado1;
            this.estado_empleado2 = anterior.estado_empleado2;            
            this.fin_entrega1 = anterior.fin_entrega1;
            this.fin_entrega2 = anterior.fin_entrega2;            
            this.fin_ticket = anterior.fin_ticket;            
            this.proxima_llegada_cliente = anterior.proxima_llegada_cliente;

            this.rnd_consumicion = -1;
            this.rnd_eleccion = -1;
            this.rnd_eleccion_consumir= -1;
            this.rnd_entrega1= -1;
            this.rnd_entrega2= -1;
            this.rnd_llegada= -1;            
            this.rnde_entrega1= -1;
            this.rnde_entrega2= -1;
            this.rndn_llegada= -1;
            this.rndu_consumicion= -1;            
            this.eleccion = -1;
            this.eleccion_consumir = -1;
            this.prox_cli_fin_comsumicion = null;
            this.prox_cli_fin_paso = null;
            this.prox_cli_fin_utilizacion = null;            

        }

        public int getTipoProximoEvento()
        {
            bool encontrado = false;
            double siguiente = double.MaxValue;
            /*FIN TICKET*/
            if (this.fin_ticket < siguiente && this.fin_ticket>0)
            {
                siguiente = this.fin_ticket;
                tipoEvento = (int)Utils.eventos.FIN_COMPRA_TICKET;
                encontrado = true;
            }
            /*FIN ENTREGA1*/
            if (this.fin_entrega1 < siguiente && this.fin_entrega1>0)
            {
                siguiente = this.fin_entrega1;
                tipoEvento = (int)Utils.eventos.FIN_ENTREGA_1;
                encontrado = true;
            }
            /*FIN ENTREGA1*/
            if (this.fin_entrega2 < siguiente && this.fin_entrega2>0)
            {                
                siguiente = this.fin_entrega2;
                tipoEvento = (int)Utils.eventos.FIN_ENTREGA_2;
                encontrado = true;
            }
         
            /*FIN UTILIZACION MESA*/
            prox_cli_fin_utilizacion = gridline.obtenerClientePorFinUtilizacion();
            if (prox_cli_fin_utilizacion != null)
            {
                if (prox_cli_fin_utilizacion.finUsoMesa < siguiente && prox_cli_fin_utilizacion.finUsoMesa > 0)
                {
                    siguiente = prox_cli_fin_utilizacion.finUsoMesa;
                    tipoEvento = (int)Utils.eventos.FIN_UTILIZACION_MESA;                    
                    encontrado = true;
                }                
            }

            /*FIN CONSUMICION*/
            this.prox_cli_fin_comsumicion = gridline.obtenerClientePorFinConsumicion();
            if (this.prox_cli_fin_comsumicion != null)
            {
                if (this.prox_cli_fin_comsumicion.finComsumicion < siguiente && this.prox_cli_fin_comsumicion.finComsumicion > 0)
                {
                    siguiente = this.prox_cli_fin_comsumicion.finComsumicion;
                    tipoEvento = (int)Utils.eventos.FIN_CONSUMICION_PEDIDO;                    
                    encontrado = true;
                }
            }

            /*FIN PASO*/
            this.prox_cli_fin_paso = gridline.obtenerClientePorFinPaso();
            if (this.prox_cli_fin_paso != null)
            {
                if (this.prox_cli_fin_paso.finPaso < siguiente && this.prox_cli_fin_paso.finPaso > 0)
                {
                    siguiente = this.prox_cli_fin_paso.finPaso;
                    tipoEvento = (int)Utils.eventos.FIN_PASO;                    
                    encontrado = true;
                }
            }

            if (this.proxima_llegada_cliente < siguiente && this.proxima_llegada_cliente>0)
            {
                siguiente = this.proxima_llegada_cliente;
                tipoEvento = (int)Utils.eventos.LLEGADA_CLIENTE;
                encontrado = true;
            }
            if (encontrado==false)
                System.Windows.Forms.MessageBox.Show("Error, no encontró próximo evento");

            return tipoEvento;
        }
       
        public void inicializar()
        {                        
            this.rnd_llegada = -1;
            this.rndn_llegada = -1;
            this.proxima_llegada_cliente = -1;
            this.rnd_eleccion = -1;
            this.eleccion = -1;
            this.fin_ticket = -1;
            this.estado_cajero = (int)Utils.cajero.LIBRE;
            this.cola_cajero = 0;
            this.cola_entrega = 0;
            this.rnd_entrega1 = -1;
            this.rnde_entrega1 = -1;
            this.fin_entrega1 = -1;
            this.estado_empleado1 = (int)Utils.empleado.LIBRE;
            this.rnd_entrega2 = -1;
            this.rnde_entrega2 = -1;
            this.fin_entrega2 = -1;
            this.estado_empleado2 = (int)Utils.empleado.LIBRE;
            this.rnd_eleccion_consumir = -1;
            this.eleccion_consumir = -1;
            this.rnd_consumicion = -1;
            this.rndu_consumicion = -1;
            //this.fin_comsumicion = -1;
            //this.rnd_utilizacion = -1;
            //this.rndu_utilizacion = -1;
            //this.fin_utilizacion = -1;
            //this.fin_paseo = -1;
            this.contador_personas = 0;
            this.acumulador_permanencia = 0;

        }

        public static bool obtenerClientePorEstado(int estado, Cliente cli)
        {          
            foreach (Cliente c in gridline.clientes)
	        {
                if (c.estado == estado)
                {
                    cli = c;
                    return true;
                }
	        }
            System.Windows.Forms.MessageBox.Show("Error. No se encontró un cliente en estado " + Enum.GetName(typeof(Utils.cliente),estado));
            return false;
        }

        public static Cliente obtenerClientePorFinUtilizacion()
        {
            double menor = double.MaxValue;
            bool encontrado =false;
            Cliente ret_cli = new Cliente();
            foreach (Cliente c in gridline.clientes)
	        {
                if (c.estado == (int)Utils.cliente.UTILIZANDO_MESA)
                {
                    if (c.finUsoMesa < menor && c.finUsoMesa > 0)
                    {
                        menor = c.finUsoMesa;
                        ret_cli = c;
                        encontrado= true;
                    }                    
                }                
	        }
            if(encontrado)
                return ret_cli;
            else
                return null;
        }

        public static Cliente obtenerClientePorFinPaso()
        {
            double menor = double.MaxValue;
            bool encontrado = false;
            Cliente ret_cli = new Cliente();
            foreach (Cliente c in gridline.clientes)
            {
                if (c.estado == (int)Utils.cliente.DEPASO)
                {
                    if (c.finPaso < menor && c.finPaso > 0)
                    {
                        menor = c.finPaso;
                        ret_cli = c;
                        encontrado = true;
                    }
                }
            }
            if (encontrado)
                return ret_cli;
            else
                return null;
        }

        public static Cliente obtenerClientePorFinConsumicion()
        {
            double menor = double.MaxValue;
            bool encontrado = false;
            Cliente ret_cli = new Cliente();
            foreach (Cliente c in gridline.clientes)
            {
                if (c.estado == (int)Utils.cliente.CONSUMIENDO)
                {
                    if (c.finComsumicion < menor && c.finComsumicion > 0)
                    {
                        menor = c.finComsumicion;
                        ret_cli = c;
                        encontrado = true;
                    }
                }
            }
            if (encontrado)
                return ret_cli;
            else
                return null;
        }
    }
}
